<?php
/* 
 MOBLOG MODULE by martin $ 2009/10/29 22:39:07
*/
/*
　ppBlog1.5 RC2 から、認証を独自のセッション管理に変えています。
　投稿処理のコアな部分は、多分にnaoKさんの尽力によるものです。
　　特にvodafone対策とか→http://ppppp.s53.xrea.com/diary/index.php
　デバッグモードもありますので、上手く投稿が出来ない方は情報を頂けたらと
　思います。
*/

include_once('owner/ini.inc.php');
include_once('utils.php');
include_once('utils_admin.php');
include_once('session.class.php');

define('MOBLOG_MAX_ISIZE', MAX_ISIZE); // 携帯投稿時の写真の大きさ指定(ピクセル)

$img_type = "gif|jpe?g|png";        // アップできる画像Content-Type
$media_type = "3gp|amc|x-mpeg";     // アップできる動画Content-Type

$sid = md5(OPASS.$_SERVER['HTTP_USER_AGENT']);

$mob_ini = OD.'mob.ini.php';

include_once(OD.'usrlist.ini.php');      // $USR_LISTの読み込み

if($mb==TRUE){
 mb_language("Japanese");
 mb_internal_encoding(ENCODE);
} else {
 if(is_file(PATH.'jcode_wrapper.php')){
  include_once(PATH.'jcode_wrapper.php');
 } else makeXHTML_mobile_mob('Multibyte Not Supported.');
}

if(isset($MOB_CFG)){ // index.php で読み込んでいれば
 $background = TRUE;
 $debug_mode = 0;
} else {
 include($mob_ini); // 設定変数の読み込み
 define('ADMIN', Auth($sid) ? TRUE : FALSE);
 $background = FALSE;
 $debug_mode = $MOB_CFG[7];
 header ("Content-Type: text/html; charset=SHIFT_JIS");
}

define('DEBUG_LOG', 'owner/moblog_debug_'.date('YmdHis').'.txt');
define('DEBUG_MODE', $debug_mode);
$mail_tff = array('&#124;', '&lt;', '&gt;', '&#44;');
$mail_tft = array('|', '<', '>', '|'); # アドレスの復元

/* ログアウト処理 */

if(defined('ADMIN') && ADMIN && g_('logoff') != ''){
 $SESSION->scavenge();
 $SESSION->destroy();
}

/* ログイン処理 */

$omatch = $umatch = FALSE;

if(!$background){
 if(p_('mobpwd') != ''){
  if(!empty($USR_LIST) && p_('mobid')==''){
   makeXHTML_mobile_mob('ログインするにはブログでのID名も必要です。');
  }
  $YID = empty($USR_LIST) ? '' : p_('mobid');
  $PWD = p_('mobpwd');
  if(($YID===OWNER || $YID=='') && $PWD===OPASS){
   $MOB_CFG = array_pad($MOB_CFG, 8, 'ERROR');
   $category = $MOB_CFG[0]=='ERROR' ? 'moblog' : $MOB_CFG[0];  // カテゴリー名
   $send_ping = $MOB_CFG[5]=='ERROR' ? 0 : $MOB_CFG[5]; // PINGサイトにpingを送信するかどうか。
   $debug_mode = $MOB_CFG[7]=='ERROR' ? 0 : $MOB_CFG[7];       // デバッグモード
   $allowC = $MOB_CFG[9]=='ERROR' ? 0 : $MOB_CFG[9];       // コメント
   $allowP = $MOB_CFG[10]=='ERROR' ? 0 : $MOB_CFG[10];     // トラックバック
   $submitter = ONAME;
   $omatch = TRUE; // オーナーID,PWDと一致
  }
  if(!$omatch){ // オーナーは不一致、共有ユーザーをサーチしてみる
   foreach ($USR_LIST as $U){
    list(,$usrid,$upwd,$alias,,,,$MOB_CFG[1],$MOB_CFG[2],$MOB_CFG[3],$MOB_CFG[4],$MOB_CFG[0],$MOB_CFG[5],$MOB_CFG[9],$MOB_CFG[10]) = explode('|', $U);
    if($YID===$usrid && $PWD===$upwd){
     $submitter = !empty($alias) ? $alias : $usrid; # 投稿者の設定
     if(empty($MOB_CFG[1]) || empty($MOB_CFG[2]) || empty($MOB_CFG[3]) ||
        empty($MOB_CFG[4])){
      makeXHTML_mobile_mob(
      'ユーザー：<strong>'.$submitter.'</strong> のモブログ情報が設定されていません。<br />
       ブログの管理者に問い合わせて下さい。
      ');
     }
     $umatch = TRUE;
     break;
    }
   } #foreach
  }

  if($omatch===TRUE || $umatch===TRUE){ // 認証完了
   $SESSION = new Session();
   if($omatch) $SESSION->data['ppBlog_OAdmin'] = "1";
   if($umatch) $SESSION->data['ppBlog_UAdmin'] = "1";

   $SESSION->data['id'] = $sid;
   $SESSION->data['ppBlog_login_name'] = my_encrypt($submitter);
   $SESSION->data['expire'] = time() + SESSION_LIFE_TIME * 60;
   $SESSION->register();                // セッション開始
   $SESSION->scavenge();
  }
 } #p_('mobpwd')

 if( empty($SESSION->data) ){
   makeXHTML_mobile_mob('
 <form method="post" action="mob.php">
 '.(empty($USR_LIST) ? 'ブログのPWDは？<br />' :
  'ブログのIDとPWDは？<br /> ID: <input type="text" name="mobid" size="8" maxlength="32" />').'
  PWD: <input type="text" name="mobpwd" size="8" maxlength="32" />
  <input type="submit" name="login" value="ログイン" />
 </form>
  ');
 }
 $MOB_CFG[1] = str_replace($mail_tff, $mail_tft, $MOB_CFG[1]); // Thanks, yasu

 /* 最終設定 */

 $category = $MOB_CFG[0];  // カテゴリー名 Thanks, BENIT!
 $moby = $MOB_CFG[1];      // 送信元ケータイのアドレス
 $server = $MOB_CFG[2];    // 送信先メルアドのPOP3サーバー
 $user = $MOB_CFG[3];      // POP3ユーザーID
 $pass = $MOB_CFG[4];      // POP3パスワード
 $allowC = $MOB_CFG[9];    // コメント
 $allowP = $MOB_CFG[10];   // トラックバック
} else { #background
 $server = $MOB_CFG[2];    // 送信先メルアドのPOP3サーバー
 $user = $MOB_CFG[3];      // POP3ユーザーID
 $pass = $MOB_CFG[4];      // POP3パスワード
 $mobies = array();
 $mobies[] = str_replace($mail_tff, $mail_tft, $MOB_CFG[1]);  # owner's
 foreach ($USR_LIST as $U){
  if(strpos($U, "$server|$user|$pass")){ # ユーザーのメールサーバーがオーナーと同じ場合に有効
   list(,,,,,,,$moby,) = explode('|', $U);
   $moby = str_replace($mail_tff, $mail_tft, $moby);
   $mobies[] = $moby;
  }
 } #foreach
 $moby = implode('|', $mobies); # メアド連結
}

$send_ping = $MOB_CFG[5]; // 更新PING

if(strstr("$moby,$server,$user,$pass", 'ERROR')){
 if($background) return;
 makeXHTML_mobile_mob('
 <p>モブログ投稿の設定が不十分のようです！</p>
 <p>モバイルモードで記事を閲覧'.(ADMIN?'(ログインしてます)':'').' -&gt; <a href="moby.php">入り口</a></p>
 <p>ログアウトするならこちら -&gt; <a href="mob.php?logoff=1">ログアウト</a></p>
 ');
}

/* ここからがコア */

$port = strstr($server, '.gmail') ? 995 : 110;
$server = strstr($server, '.gmail') ? 'ssl://'.$server : $server;

if(!$fp = @fsockopen($server, $port, $errno, $errstr, $timeout=10)){
 if($background) return;
 makeXHTML_mobile_mob('<p>サーバー接続エラー[moblog] ('.$errno.') - '.$errstr.'</p>'.NL);
}
socket_set_timeout($fp, $timeout);
if(!preg_match('/\+OK/', $line=fgets($fp, 512))){
 if($background){
  $MOB_CFG[8] = time();
  rewrite_ini($mob_ini, $MOB_CFG);
  return;
 }
 die($line);
}
pop3_cmd($fp, "USER $user");
pop3_cmd($fp, "PASS $pass");

list($count,) = sscanf(pop3_cmd($fp, "STAT"), '+OK %d %d');

$emptyMsg = '
 <p>今のところモブログメールはありません。</p>
 <p>モバイルモードで記事を閲覧しますか？ -&gt; <a href="moby.php">入り口</a></p>
 <p>ログアウトするならこちら -&gt; <a href="mob.php?logoff=1">ログアウト</a></p>
';

if($count==0){
 pop3_cmd($fp, "QUIT");
 fclose($fp);
 if($background){
  $MOB_CFG[8] = time();
  rewrite_ini($mob_ini, $MOB_CFG);
  return;
 }
 makeXHTML_mobile_mob($emptyMsg);
}

$moby_mail = 0;

$logFormat = $imgs_list = $media_list = array();

for ($i=1; $i <= $count; $i++){
 $line = pop3_cmd($fp, "RETR $i");
 $data = '';
 while (!preg_match('/^\.\r\n/', $line)){
  $line = fgets($fp, 512);
  $data .= $line;
 }
 $data = preg_replace("{\r\n?}", NL, $data);
 $data = my_convert_encoding($data, ENCODE, 'JIS');
 if(DEBUG_MODE){
  $data = preg_replace("{(:?\s?|<)[0-9a-z\.\-\_!#$%&]+?@[^.]+\..+>?}i", " foo@example.com", $data);
  rewrite(DEBUG_LOG, $data); // for debugging
  makeXHTML_mobile_mob('
   <p>デバッグモードです。メール内容は'.DEBUG_LOG.'で確認できます。</p>
   <p>送信したメールはサーバー上に残っていますので、デバッグモードを<br />
    解除すれば通常のエントリーが再開できます。</p>
  ');
 }
 if(preg_match("{From:.*($moby).*?\n}", $data, $mt_from)){  // 指定ケータイからのメールなら
  include_once('cache.php');
  if($background){ // 自動投稿モード時
   $owner_mail = str_replace($mail_tff, $mail_tft, $MOB_CFG[1]);
   $mail_from = trim($mt_from[1]);
   if(strstr($owner_mail, $mail_from)){
    $submitter = ONAME; $category = $MOB_CFG[0]; $allowC = $MOB_CFG[9]; $allowP = $MOB_CFG[10];
   } else {
    foreach($USR_LIST as $U){
     if(strpos($U, $mail_from)){
      list(,$yid,,$alias,,,,,,,,$category,,$allowC,$allowP,) = explode('|', $U);
      $submitter = empty($alias) ? $yid : $alias;
      break;
     }
    }
   }
  } else { # not background
   $submitter = empty($submitter) ? my_decrypt($SESSION->data['ppBlog_login_name']) : $submitter;
  } 
  $moby_mail++;
  if(preg_match("{\nDate:([^\n]+)}", $data, $mt_date)){
   $uid = strtotime(trim($mt_date[1])) != -1 ? strtotime(trim($mt_date[1])) : time();
  }
  if(!isset($uid) || empty($uid)) $uid = time();
  if(preg_match('{Content-type:(?:.*?)(image|application|video|multipart)/(.+?);}i', $data, $ctype)){
   if($ctype[2] == 'related') {   // for vodafone
    preg_match('{.*boundary="([^"]+)".+boundary="([^"]+)"}is', $data, $mt_spliter);
    list($header, $body, $attached) = explode("--$mt_spliter[1]", $data);
    list(, $body) = explode("--$mt_spliter[2]", $body);
    list(, $body) = explode(NL.NL, $body, 2);
   } elseif ($ctype[2] == 'alternative') {   // HTML mail
    preg_match('{.*boundary="([^"]+)"}i', $data, $mt_spliter);
    list($header, $body, $html) = explode("--$mt_spliter[1]", $data);
    list(, $body) = explode(NL.NL, $html, 2); $attached = '';
    $body = str_replace(array('<br>'), array('<br />'), trim($body));
   } elseif(!stristr($ctype[1], 'multipart')){    // for vodafone 本文なし
    list($header,) = explode(NL.NL, $data);
    $body = ''; $attached = $data;
   } else { //画像つき
    preg_match('{.*boundary="?([^"\r\n]+)"?}i', $data, $mt_spliter);
    list($header, $body, $attached) = explode("--$mt_spliter[1]", $data, 3);
    if(!stristr($attached, 'image/') && !stristr($attached, 'video/')){
     if($body == ''){
      $attached = $body; $body = '';
     } else list(,$body) = explode(NL.NL, $body, 2);
    } else list(,$body) = explode(NL.NL, $body, 2);
   }
   if(preg_match('{(------=.+?)\n}', $body, $mt_spliter2)){
    list(,,$body) = explode("$mt_spliter2[1]", $body, 3); // text/html possible
    list(,$body) = explode(NL.NL, $body, 2);
    $body = str_replace(array($mt_spliter2[1].'--', '<br>'), array('', '<br />'), trim($body));
   }
   $body = convert_str(trim($body));
   if($attached){
    $PICS = explode("--$mt_spliter[1]", $attached);
    foreach ($PICS as $j => $pic){
     if(!stristr($pic, 'name')) continue;
     $ix = $j + 1;
     list($a_h, $a_b) = explode(NL.NL, $pic);   
    
     $a_h = str_replace(array('.JPG','.JPEG','.GIF','.PNG','.3GP','.AMC'),
                        array('.jpg','.jpg','.gif','.png','.3gp','.amc'), $a_h);
     if(preg_match('{\s*?name="?([^"\n]+)"?}', $a_h, $mt_img) && eregi("image/($img_type)", $a_h, $mt_ext)){ // IMG
      if(strpos($mt_img[1], $mt_ext = str_replace('e', '', $mt_ext[1]) )){
       $img_name = $uid.'_'.str_replace(".$mt_ext", '', $mt_img[1]).'.'.$mt_ext;
      } else $img_name = $uid.'_'.$ix.'_moby.'.$mt_ext;
      $imgs_list[$moby_mail][] = IMG_DIR.$img_name;
      $img_file = base64_decode($a_b);
      $_fp = fopen(IMG_DIR.$img_name, 'wb');
      fputs($_fp, $img_file);
      fclose($_fp);
    
      list($w, $h,) = getImageSize(IMG_DIR.$img_name);
      $ratio0 = MOBLOG_MAX_ISIZE / max($w, $h);
      if($ratio0 < 1 && GD){ // 指定サイズより大きければ
       create_thumbnail(IMG_DIR.$img_name, IMG_DIR.$img_name, $w, $h, $ratio0);
      }
      list($w, $h,) = getImageSize(IMG_DIR.$img_name);
      $ratio = MAX_ISIZE / max($w, $h);
      if($ratio < 1 && GD){ // 記事表示サイズより大きければ
       create_thumbnail(IMG_DIR.$img_name, $thumb2img=IMG_DIR.THUMB2.$img_name, $w, $h, $ratio);
       list($t2w,$t2h,) = getimagesize($thumb2img);
      } else $t2w = $t2h = 0;
      $fsize = (@filesize(IMG_DIR.$img_name) > 0) ? round(filesize(IMG_DIR.$img_name)/1024,2) : 0;
      $pop = $w.'(W)×'.$h.'(H) '.$fsize;
      if(strpos($body, 'pict'.$ix.'_l')){
       $pic_align = 'left';
      } elseif (strpos($body, 'pict'.$ix.'_c')){
       $pic_align = 'center';
      } elseif (strpos($body, 'pict'.$ix.'_r')){
       $pic_align = 'right';
      } else $pic_align = PICTURE_ALIGN;
      $pict = '<img src="'.IMG_DIR.$img_name.'" alt="'.$fsize.':'.$w.':'.$h.':'.$t2w.':'.$t2h.':'.$pop.':'.$pic_align.':'.PICTURE_SHADOW.':'.PICTURE_BORDER.'::"/>';
      if(strpos($body, '%pict'.$ix)){
        $body = str_replace(array('%pict'.$ix.'_l', '%pict'.$ix.'_c', '%pict'.$ix.'_r', '%pict'.$ix), $pict, $body);
      } else $body = $pict.$body;
     } #IMG
     if(eregi('[[:space:]]*name="?([^"]+)"?'.NL, $a_h, $mt_img) && 
        eregi("(application|video)/($media_type)", $a_h, $mtype)){ // MEDIA
      if(!empty($mt_img[1])) list($name, $ext) = explode('.', $mt_img[1], 2);
      if(strstr($mtype[2], $ext)){
       $media_name = $uid.'_'.$name.'.'.$mtype[2];
      } else $media_name = $uid.'_'.($j+1).'_media.'.array_pop(explode(".",$mt_img[1]));
     
      $media_list[$moby_mail][] = MEDIA_DIR.$media_name;
      $media_file = base64_decode($a_b);
      $media_type = "$mtype[1]/$mtype[2]";
      $_fp = fopen(MEDIA_DIR.$media_name, 'wb');
      fputs($_fp, $media_file);
      fclose($_fp);
      $media_size = round(filesize(PATH.MEDIA_DIR.$media_name)/1024,1);
      $body .= '[media:'.$media_name.':'.$media_size.':'.$media_type.'/]';
     }
    } #foreach
   } #attched
  } else {                                                                         // プレーンテキスト
   list($header, $body,) = explode(NL.NL, $data, 2);
   $body = convert_str(preg_replace("/^\.\n$/m",'',$body));
  }
  preg_match('{^(?:Subject:\s?(.+?)$'.NL.')}ims', $header, $mt_subject);
  $subject = '';
  if(isset($mt_subject[1])){
   foreach (preg_split("{\s}", $mt_subject[1]) as $subj){
    if(preg_match('{=\?iso\-2022\-jp\?B\?([^\?]+)\?=}i', $subj, $mt)){
     $subject .= convert_str(base64_decode($mt[1]))." ";
    } else $subject .= $subj." ";
   }
   $subject = str_replace('[SPAM]', '', $subject);
  }
  $subject = trim($subject)=='' ? 'タイトルなし' : trim($subject);
  $delim = "  |　　"; # 区切りの文字(正規表現。 . \ + * ? [ ^ ] $ ( ) { } = ! < > | :以外の文字を指定)
  if(preg_match("{(.+?)(?:$delim)(.+$)}", $subject, $mt)){
   $subject = $mt[1]; $index = trim($mt[2]);
   $index = @mb_convert_kana($index, 'n') or $index;
   if(is_numeric($index) && $index > 0){
    include_once (OD.'category.ini.php');
    list($category,) = explode("\t", $CATEGORY_LIST[$index - 1], 2);
   }
  }
  if(trim($body)=='') $body = '本文なし';
  $logFormat[$moby_mail] = $uid.'|'.trim($category).'|'.trim($subject).'|'.rtrim($body).'|'.$submitter.'|'.$allowC.'|'.$allowP.'|||'.NL;
  if(log_($uid)=='') mk_fl(LOG.date('Ym', $uid).EXT);
 } else continue;
 pop3_cmd($fp, "DELE $i"); // メールの削除
}
pop3_cmd($fp, "QUIT");
fclose($fp);

$result = '';

if($moby_mail > 0){
 $mode = 'submit';
 $target = file( log_($uid) );// ターゲットログ
 for($j=1; $j <= $moby_mail; $j++){
  usort($target, 'SORT_BY_DATE'); // 日付の新しい順に
  array_unshift($target, $logFormat[$j]); // 先頭に追加
  $uid = substr($logFormat[$j], 0, 10);
  if(strpos($logFormat[$j], '|')) rewrite(log_($uid), $target);
  update_cache(array('recently', 'category', 'articles_volume'), $uid);
  if(!empty($imgs_list[$j]))  mod_images_DB($imgs_list[$j]);
  if(!empty($media_list[$j])) mod_images_DB($media_list[$j]);
  $result .= "エントリー成功! moblog: $j OK!<br />";
 }

 $result .= '<p>ケータイモードで記事を閲覧しますか？ -&gt; <a href="moby.php">Enter</a></p>';
 if(RSS2){
  include_once('modules/rss2.0.inc.php');
  createRSS20(time());
 }
 if(ATOM10){
  include_once('modules/atom1.0.inc.php');
  createATOM10(time());
 }
 if($send_ping){
  include_once ('xmlrpc.php');
  $result .= send_ping_xmlrpc(BLOG_NAME, ROOT_PATH.'index.php');
 }
 if($background){
  $MOB_CFG[8] = time();
  rewrite_ini($mob_ini, $MOB_CFG);
  return;
 } else makeXHTML_mobile_mob($result);
} else {
 if($background){
  $MOB_CFG[8] = time();
  rewrite_ini($mob_ini, $MOB_CFG);
  return;
 }
 makeXHTML_mobile_mob($emptyMsg);
}

function pop3_cmd($fp, $cmd){
 fputs($fp, $cmd."\r\n");
 if(preg_match('/\+OK/',$line=fgets($fp, 512))) {
  return $line;
 } else die($line);
}

function convert_str($str){
 global $_FILTER1;
 $str = my_convert_encoding($str, ENCODE, 'auto');
 $str = str_replace(array_keys($_FILTER1), array_values($_FILTER1), $str);
 return preg_replace("/\r\n|\r|\n/",'`', $str);
}
function makeXHTML_mobile_mob($body='', $title=BLOG_NAME, $css=''){ // about 500bytes with body empty
 $xml = preg_match('/docomo\/1.0/i', $_SERVER['HTTP_USER_AGENT']) ? '' :
      '<?xml version="1.0" encoding="shift_jis"?>';
 $h = $xml.'
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">
<head>
 <meta http-equiv="content-type" content="text/html;charset=shift_jis" />
 <meta http-equiv="content-style-type" content="text/css" />
 <title>'.my_convert_encoding($title, "SJIS", ENCODE).'</title>
</head>
<body>
'.my_convert_encoding($body, "SJIS", ENCODE).'
</body>
</html>
';
 die(trim($h));
}
?>
